package com.micro.ai.agents.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.agents.entity.Conversation;
import com.micro.ai.agents.mapper.ConversationMapper;
import com.micro.ai.agents.service.ConversationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 会话服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class ConversationServiceImpl extends ServiceImpl<ConversationMapper, Conversation> implements ConversationService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Conversation create(Conversation conversation) {
        if (conversation == null) {
            throw new BusinessException("A0000", "会话信息不能为空");
        }
        
        if (!StringUtils.hasText(conversation.getTenantId())) {
            throw new BusinessException("A0000", "租户ID不能为空");
        }
        
        if (!StringUtils.hasText(conversation.getAgentId())) {
            throw new BusinessException("A0000", "智能体ID不能为空");
        }
        
        if (!StringUtils.hasText(conversation.getUserId())) {
            throw new BusinessException("A0000", "用户ID不能为空");
        }
        
        if (conversation.getMessageCount() == null) {
            conversation.setMessageCount(0);
        }
        if (conversation.getTotalTokensUsed() == null) {
            conversation.setTotalTokensUsed(0);
        }
        if (conversation.getStatus() == null) {
            conversation.setStatus("active");
        }
        
        LocalDateTime now = LocalDateTime.now();
        conversation.setStartedAt(now);
        conversation.setCreatedAt(now);
        
        boolean success = this.save(conversation);
        if (!success) {
            throw new BusinessException("A0003", "保存会话失败");
        }
        
        log.info("创建会话成功: conversationId={}, agentId={}, userId={}", 
                conversation.getId(), conversation.getAgentId(), conversation.getUserId());
        return conversation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Conversation update(String id, Conversation conversation) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("A0000", "会话ID不能为空");
        }
        if (conversation == null) {
            throw new BusinessException("A0000", "会话信息不能为空");
        }
        
        Conversation existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("A0002", "会话不存在: " + id);
        }
        
        conversation.setId(id);
        
        boolean success = this.updateById(conversation);
        if (!success) {
            throw new BusinessException("A0003", "更新会话失败");
        }
        
        log.info("更新会话成功: conversationId={}", id);
        return conversation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("A0000", "会话ID不能为空");
        }
        
        Conversation conversation = this.getById(id);
        if (conversation == null) {
            throw new BusinessException("A0002", "会话不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("A0003", "删除会话失败");
        }
        
        log.info("删除会话成功: conversationId={}", id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void close(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("A0000", "会话ID不能为空");
        }
        
        Conversation conversation = this.getById(id);
        if (conversation == null) {
            throw new BusinessException("A0002", "会话不存在: " + id);
        }
        
        conversation.setStatus("closed");
        conversation.setEndedAt(LocalDateTime.now());
        
        boolean success = this.updateById(conversation);
        if (!success) {
            throw new BusinessException("A0003", "关闭会话失败");
        }
        
        log.info("关闭会话成功: conversationId={}", id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void archive(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("A0000", "会话ID不能为空");
        }
        
        Conversation conversation = this.getById(id);
        if (conversation == null) {
            throw new BusinessException("A0002", "会话不存在: " + id);
        }
        
        conversation.setStatus("archived");
        if (conversation.getEndedAt() == null) {
            conversation.setEndedAt(LocalDateTime.now());
        }
        
        boolean success = this.updateById(conversation);
        if (!success) {
            throw new BusinessException("A0003", "归档会话失败");
        }
        
        log.info("归档会话成功: conversationId={}", id);
    }

    @Override
    public Page<Conversation> pageQuery(int pageNum, int pageSize, String tenantId, 
                                       String agentId, String userId, String status) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<Conversation> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Conversation> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(Conversation::getTenantId, tenantId);
        }
        if (StringUtils.hasText(agentId)) {
            query.eq(Conversation::getAgentId, agentId);
        }
        if (StringUtils.hasText(userId)) {
            query.eq(Conversation::getUserId, userId);
        }
        if (StringUtils.hasText(status)) {
            query.eq(Conversation::getStatus, status);
        }
        
        query.orderByDesc(Conversation::getLastMessageAt)
             .orderByDesc(Conversation::getCreatedAt);
        
        return this.page(page, query);
    }

    @Override
    public List<Conversation> listByUserId(String tenantId, String userId, String status) {
        LambdaQueryWrapper<Conversation> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(Conversation::getTenantId, tenantId);
        }
        if (StringUtils.hasText(userId)) {
            query.eq(Conversation::getUserId, userId);
        }
        if (StringUtils.hasText(status)) {
            query.eq(Conversation::getStatus, status);
        }
        
        query.orderByDesc(Conversation::getLastMessageAt)
             .orderByDesc(Conversation::getCreatedAt);
        
        return this.list(query);
    }
}

